MySQL RouterでRDSのReplicaを負荷分散してみる
ウィスキー、シガー、パイプをこよなく愛する大栗です。
MySQLやAuroraでRead Heavyな環境だとだとRead Replicaを多数用意すると思います。多数のRead Replicaを効率的に使用するためにはリクエストの負荷分散が必須です。MySQLの負荷分散を行うためのプロダクトはいくつかありますが、今回はMySQL Routerを試してみました。
MySQL Router
プロダクトのページにトップには、以下の様な記載があります。透過的なルーティングと言うことで、MySQLに接続するつもりでMySQL Routerに接続すれば良いということです。
MySQL Routerはアプリケーションと任意のバックエンドのMySQLサーバー間の透過的なルーティングを提供する軽量のミドルウェアです。データベースへの接続を適切なバックエンドのMySQLサーバーへ効果的に ルーティングすることにより、高可用性や拡張性の提供など、様々なユースケースで使用できます。
類似のプロダクトでは、代表的なものに以下の様なものがあります。
- MySQL専用プロダクト
- MySQL Proxy(Alpha版なので本番環境の利用は推奨されません)
- MaxScale:クエリのフィルタリングなどが可能な多機能のMySQL用プロキシサーバです。MaxScale 2.0からBusiness Source Licensing (BSL)というライセンスが採用されています。
- ProxySQL:MaxScaleと比較して高速だという調査があるようです。
- 汎用プロトコルのプロダクト
MySQL Routerをインストールしてみる
以下の環境に導入してみます。
- OS:Amazon Linux 2016.03
- EC2:t2.small
- リージョン:東京
Download MySQL Yum RepositoryのページからリポジトリのRPMをダウンロードします。Amazon Linuxでは『Red Hat Enterprise Linux 6 / Oracle Linux 6 (Architecture Independent), RPM Package』のパッケージを選択します。2016年8月31日現在でファイル名はmysql57-community-release-el6-8.noarch.rpm
となっています。
パッケージをインストールしてMySQLのリポジトリを登録します。
$ sudo rpm -Uvh /path/to/mysql57-community-release-el6-8.noarch.rpm
MySQL Routerをインストールします。
$ sudo yum install mysql-router -y
設定ファイルは、/etc/mysqlrouter/mysqlrouter.ini
にあります。
# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # MySQL Router configuration file # # Documentation is available at # http://dev.mysql.com/doc/mysql-router/en/ [DEFAULT] logging_folder = /var/log/mysqlrouter/ plugin_folder = /usr/lib64/mysqlrouter runtime_folder = /var/run/mysqlrouter config_folder = /etc/mysqlrouter [logger] level = info # If no plugin is configured which starts a service, keepalive # will make sure MySQL Router will not immediately exit. It is # safe to remove once Router is configured. [keepalive] interval = 60
MySQL Routerを構成する
MySQL for RDSでMasterが1台、Read Replicaが2台の環境に対して、以下のように設定してみます。MySQL Routerの受付ポートはMaster側を13306、Read Replica側を23306として設定します。
mysqlrouter.iniは以下のように構成しました。37行目以降を追加しています。Masterへ向ける接続はread-write
モードに設定して、Replicaに向ける接続はread-only
モードに設定して負荷分散をしています。
# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # MySQL Router configuration file # # Documentation is available at # http://dev.mysql.com/doc/mysql-router/en/ [DEFAULT] logging_folder = /var/log/mysqlrouter/ plugin_folder = /usr/lib64/mysqlrouter runtime_folder = /var/run/mysqlrouter config_folder = /etc/mysqlrouter [logger] level = info # If no plugin is configured which starts a service, keepalive # will make sure MySQL Router will not immediately exit. It is # safe to remove once Router is configured. [keepalive] interval = 60 [routing:master] bind_address = 0.0.0.0:13306 destinations = master.abcdefghijkl.ap-northeast-1.rds.amazonaws.com mode = read-write [routing:replica] bind_address = 0.0.0.0:23306 destinations = slave1.abcdefghijkl.ap-northeast-1.rds.amazonaws.com,slave2.abcdefghijkl.ap-northeast-1.rds.amazonaws.com mode = read-only
動作を確認してみる
MySQL Routerへ接続して動作を確認してみます。
まずはMasterへ接続してみます。
$ mysql -u awsuser -p -P 13306 -h 127.0.0.1 Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 91 Server version: 5.6.27-log MySQL Community Server (GPL) Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show variables like 'hostname'; +---------------+--------------+ | Variable_name | Value | +---------------+--------------+ | hostname | ip-10-7-2-19 | +---------------+--------------+ 1 row in set (0.00 sec) mysql>
ますはMasterへ接続してみます。次にReplicaへ接続してみます。
$ mysql -u awsuser -p -P 23306 -h 127.0.0.1 Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 17 Server version: 5.6.27 MySQL Community Server (GPL) Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show variables like 'hostname'; +---------------+---------------+ | Variable_name | Value | +---------------+---------------+ | hostname | ip-10-7-2-140 | +---------------+---------------+ 1 row in set (0.00 sec) mysql>
負荷分散されているか、Replica側に連続してアクセスしてホスト名を確認してみます。以下のように交互に異なるインスタンスへアクセスしていることが分かります。
$ echo "show variables like 'hostname';" | mysql -u awsuser -pmypassword -P 23306 -h 127.0.0.1 Variable_name Value hostname ip-10-7-1-94 $ echo "show variables like 'hostname';" | mysql -u awsuser -pmypassword -P 23306 -h 127.0.0.1 Variable_name Value hostname ip-10-7-2-140 $ echo "show variables like 'hostname';" | mysql -u awsuser -pmypassword -P 23306 -h 127.0.0.1 Variable_name Value hostname ip-10-7-1-94 $ echo "show variables like 'hostname';" | mysql -u awsuser -pmypassword -P 23306 -h 127.0.0.1 Variable_name Value hostname ip-10-7-2-140
さいごに
MySQL Routerを使用するとアプリに手を入れずに、手軽にReplicaの負荷分散ができるようになります。まだ、名前解決のキャッシュ状況などを検証できていないので実運用での活用方法が確認できていないので、今後検証を進めていきたいと思います。